﻿using Fozzy.Being;
using Fozzy.Gedcom;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Documents;

namespace Fozzy.Family
{
    public class Person2                         : Fozzy.Gedcom.Person2
    {
        #region States
            /// <summary>
            /// Completion is measured based on the completion of the Parents
            /// </summary>
            public override bool                        Be_Complete     { get { return base.Parents.Be_Complete                             ; } }
            public override bool                        Be_Error        { get { return base.Parents.Be_Empty                                ; } }
            //public override bool                        Forget_able     { get { return Test_Forgetable()                                    ; } }

            public bool                                 Be_Current(Person partner)  { return false                                          ; }

            private bool                                Have_Story      { get { return this.Exist(Story)                                    ; } }
        #endregion

        #region Properties
        #endregion
            
        #region Age
            public string                               Birth_Date_Place{ get { return Birth.ToString() + Statics.Space +  Birth_Place      ; } }
            public string                               Birth_Place     { get { return Relations<Place>(Fozzy.Being.relation.Birth_Place).FirstOrDefault().ToString(); } }
            public string                               Death_Place     { get { return Relations<Place>(Fozzy.Being.relation.Death_Place).FirstOrDefault().ToString(); } }

            public Age_Group                            Age_Group       { get { return new Age_Group(Age())                                 ; } }
            public Relative_Age                         Relative_Age    { get { return new Relative_Age(Birth, Death)                       ; } }
        #endregion

        #region Photos
            public IEnumerable<Photo>                   Photos          { get { return Parts.Instances.Cast<Photo>()                            ; } }
            protected Photo                             Identity        { get { return Relations<Photo>(Fozzy.Family.relation.Identity).First() ; } }
        #endregion

        #region Story
            public Story                                Story           { get { return new Story(Name)                                      ; } }
            private TextRange                           Text(FlowDocument doc) { return new TextRange(doc.ContentStart, doc.ContentEnd)     ; }
        #endregion

        #region Family
            /// <summary>
            /// True physical Relation Parent-Child
            /// </summary>
            public IEnumerable<Person>                  _Children       { get { return Relations<Person>(Fozzy.Family.relation.Child)       ; } }
            /// <summary>
            /// True physical Relation Child-Parent
            /// </summary>
            public IEnumerable<Person>                  Partners        { get { return Relations<Person>(Fozzy.Family.relation.Partner)     ; } }
            public Fozzy.Being.Parents                  Parent(Person partner) { return new Fozzy.Being.Parents(this, partner)              ; }
            /// <summary>
            /// Logical Relation obtained by analysis of the Child-Parent relation
            /// </summary>
            public IEnumerable<Person>                  _Parents        { get { return Relations<Person>(Fozzy.Family.relation.Parent)      ; } }
            /// <summary>
            /// Logical Relation obtained by analysis of the Child-Parent relation
            /// </summary>
            public IEnumerable<Person>                  _Siblings       { get { return _Parents.Children().Except(this).Cast<Person>()      ; } }
            /// <summary>
            /// This Relation is not implemented as Physical Relation in the Fozzy.Being 
            /// It needs to be computed on demand
            /// </summary>
            public IEnumerable<Person>                  _Half_Siblings  { get { return (new Person[] { Father, Mother}).Children().Except(this).Cast<Person>() ; } }
        #endregion
       
        #region Constructeur
            public Person2()
            {}
            public Person2(Fozzy.Being.Person person)                    : base(person.Element)
            {
                //Life.Set(0, birth)                                      ;
            }
            public Person2(string first, string last, Fozzy.Time.Date birth, Fozzy.Being.gender gender)
                                                                        : this(new Fozzy.Being.Person(new Fozzy.Name(first, last),birth,gender))
            {}
        #endregion

        #region Skills
        #endregion

        #region Relations
            /// <summary>
            /// If a Person is involved in one of the Relations conveyed by the Family (Child, Couple)
            /// Then the Relations of this Person are enriched.
            /// </summary>
            /// <param name="family"></param>
            public override void Relate(IConcept family)
            {
                ((Family)family).Relate(this)                           ;
            }

            /// <summary>
            /// Argh : Ici on ne voit pas le côté bidirectionnel ...
            /// </summary>
            /// <param name="spouse"></param>
            public void Set_Spouse(Person spouse)
            {
                Relate(new Couple(spouse))                              ;
            }

            /// <summary>
            /// This method is triggered when the Photo has been incorporated as Part of a IConcept considered as the owner. 
            /// </summary>
            /// <param name="owner"></param>
            public override void Relate(IName photo, int pos)
            {
                if (pos == 0)
                {
                    Photo Photo = (Photo)photo                      ;
                    Photo.Be_Avatar = new Boolean(true)             ;
                    Relate(Photo)                                   ;
                }
            }

            public void Born(Fozzy.Time.Date birth_Date)
            {
                Life.Start(birth_Date)                              ;
            }

            public void Born(Fozzy.Space.Place place)
            {
                Live(Fozzy.Being.relation.Birth_Place, place)       ;
            }

            public void Set(Photo photo)
            {
                Relate(photo)                                       ;
            }

            public void Set(gender gender)
            {
                Gender.Set(gender)                                  ;
            }

            private void Relate(Photo photo)
            {
                //Relate(new Avatar(photo))                  ;
            }

            public void Load()
            {
                // store the stories into temp directory to be packaged into OPC later
                //Directory.Store<Photo>(Photos)  ;
                //Directory.Store<Story>(Story)   ;
            }

            public void Load(FlowDocument doc)
            {
                Story.Load(Text(doc))                                                                   ;
            }

            public void Save(FlowDocument doc)
            {
                //Story = new Story();
                //string storyFileName = new StringBuilder(person.Name.ToString()).Append(".rtf").ToString();
                Story.Write(Text(doc))                                                                   ;
            }

            private void Delete()
            {
                if (Have_Story) 
                {
                    Story.Delete()              ;
                    //Story = null                ;
                }
            }

            private bool Test_Forgetable()
            {
                // With a few exceptions, anyone with less than 3 relationships is deletable
                //if (relationships.Count < 3)
                //{
                //    // The person has 2 spouses. Since they connect their spouses, they are not deletable.
                //    if (Spouses.Count == 2)
                //        return false;

                //    // The person is connecting two generations
                //    if (Parents.Count == 1 && Children.Count == 1)
                //        return false;

                //    // The person is connecting inlaws
                //    if (Parents.Count == 1 && Spouses.Count == 1)
                //        return false;

                //    // Anyone else with less than 3 relationships is deletable
                //    return true;
                //}

                //// More than 3 relationships, however the relationships are from only Children. 
                //if (Children.Count > 0 && Parents.Count == 0 && Siblings.Count == 0 && Spouses.Count == 0)
                //    return true;

                //// More than 3 relationships. The relationships are from siblings. Deletable since siblings are connected to each other or the parent.
                //if (Siblings.Count > 0 && Parents.Count >= 0 && Spouses.Count == 0 && Children.Count == 0)
                //    return true;

                // This person has complicated dependencies that does not allow deletion.

                return false                    ;
            }
        #endregion

    }
}
